<?php
declare(strict_types=1);
namespace cms\wechat\service;

use cms\wechat\model\OfficialModel;
use EasyWeChat\Factory;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Guzzle\CoroutineHandler;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Utils\ApplicationContext;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\HttpFoundation\HeaderBag;
use Symfony\Component\HttpFoundation\Request;

class OfficialService extends CommonService
{
    /**
     * @Inject()
     * @var OfficialModel
     */
    public OfficialModel $model;

    /**
     * @Inject()
     * @var AuthorizeService
     */
    protected AuthorizeService $authorizeService;

    /**
     * @Inject()
     * @var PlatformService
     */
    protected PlatformService $platformService;

    public function initApplication(OfficialModel $official)
    {
        // 已经授权第三方
        $authorize = $this->authorizeService->model->where([
            ['app_id', '=', $official->app_id]
        ])->first();
        if ($authorize) {
            return $this->platformService->initApplication($authorize->platform)->officialAccount($official->app_id, $authorize->refresh_token);
        }
        // 实例化公众号应用
        $application = Factory::officialAccount([
            'app_id' => $official->app_id,
            'secret' => $official->app_secret,
            'token' => $official->app_token,
            'aes_key' => $official->app_key,
        ]);

        // region 替换请求 +++++
        $request = ApplicationContext::getContainer()->get(RequestInterface::class);
        $get = $request->getQueryParams();
        $post = $request->getParsedBody();
        $cookie = $request->getCookieParams();
        $uploadFiles = $request->getUploadedFiles() ?? [];
        $server = $request->getServerParams();
        $xml = $request->getBody()->getContents();
        $files = [];
        /** @var \Hyperf\HttpMessage\Upload\UploadedFile $v */
        foreach ($uploadFiles as $k => $v) {
            $files[$k] = $v->toArray();
        }
        $new_request = new Request($get, $post, [], $cookie, $files, $server, $xml);
        $new_request->headers = new HeaderBag($request->getHeaders());
        $application->rebind('request', $new_request);
        // endregion


        $handler = new CoroutineHandler();
        $stack = HandlerStack::create($handler);
        // 设置HttpClient
        $http_config = $application->config->get('http', []);
        $http_config['handler'] = $stack;
        $application->rebind('http_client', new Client($http_config));
        $application->guzzle_handler = $handler;
        $application->oauth->setGuzzleOptions([
            'http_errors' => false,
            'handler' => $stack
        ]);

        $cache = ApplicationContext::getContainer()->get(CacheInterface::class);
        $application->rebind('cache', $cache);
        return $application;
    }

    public function syncDataByAuth(array $info = [])
    {
        $data = [
            'app_id' => $info['authorization_info']['authorizer_appid'],
            'name' => $info['authorizer_info']['nick_name'],
            //别名
            'alias' => $info['authorizer_info']['alias'],
        ];
        // 账号类型
        if ($info['authorizer_info']['service_type_info']['id'] == 2) { // 服务号
            if (in_array($info['authorizer_info']['verify_type_info']['id'], [0, 1, 2])) {
                $data['level'] = 4;
            } else {
                $data['level'] = 3;
            }
        } else { // 订阅号
            if (in_array($info['authorizer_info']['verify_type_info']['id'], [0, 1, 2])) {
                $data['level'] = 2;
            } else {
                $data['level'] = 1;
            }
        }
        // 头像
        $data['avatar'] = $info['authorizer_info']['head_img'];
        // 二维码
        $data['two_code'] = $info['authorizer_info']['qrcode_url'];
        // 原始ID
        $data['original_id'] = $info['authorizer_info']['user_name'];
        return $this->model->firstOrCreate([
            'app_id' => $data['app_id']
        ], $data);
    }
}